// PalDoc.cpp : implementation file
//

#include "stdafx.h"
#include "U7FileTool.h"
#include "PalDoc.h"

#include <algorithm>

// CPalDoc

IMPLEMENT_DYNCREATE(CPalDoc, CDocument)

CPalDoc::CPalDoc()
{
	m_pPaletteFlexFile = NULL;
}

BOOL CPalDoc::OnNewDocument()
{
	if (!CDocument::OnNewDocument())
		return FALSE;
	return TRUE;
}

CPalDoc::~CPalDoc()
{
	if ( m_pPaletteFlexFile )
		delete [] m_pPaletteFlexFile;
}

int CPalDoc::GetPaletteCount() const
{
	if ( m_pPaletteFlexFile )
		return ((PFLEXFILEHEADER)m_pPaletteFlexFile)->count;

	return 0;
}

PCOLORENTRY CPalDoc::GetPaletteFile(UINT index) const
{
	if ( m_pPaletteFlexFile )
	{
		PFLEXFILEHEADER pHeader = (PFLEXFILEHEADER)m_pPaletteFlexFile;
		if ( index < (UINT)pHeader->count )
		{
			PFLEXFILEENTRY pEntry = (PFLEXFILEENTRY)(pHeader+1);
			pEntry += index;
			if ( pEntry->size != 0 )
				return (PCOLORENTRY)(m_pPaletteFlexFile + pEntry->offset);
		}
	}

	return NULL;
}

BEGIN_MESSAGE_MAP(CPalDoc, CDocument)
END_MESSAGE_MAP()


// CPalDoc diagnostics

#ifdef _DEBUG
void CPalDoc::AssertValid() const
{
	CDocument::AssertValid();
}

#ifndef _WIN32_WCE
void CPalDoc::Dump(CDumpContext& dc) const
{
	CDocument::Dump(dc);
}
#endif
#endif //_DEBUG

#ifndef _WIN32_WCE
// CPalDoc serialization

void CPalDoc::Serialize(CArchive& ar)
{
	if (ar.IsStoring())
	{
		// TODO: add storing code here
	}
	else
	{
		// TODO: add loading code here
		CFile* pFile = ar.GetFile();

		UINT uiFileLength = (UINT)pFile->GetLength();
		m_pPaletteFlexFile = new BYTE[uiFileLength];
		if ( !m_pPaletteFlexFile )
			AfxThrowMemoryException();

		if ( pFile->Read( m_pPaletteFlexFile, uiFileLength ) != uiFileLength )
			AfxThrowFileException(CFileException::genericException,100);

		// sanity check!!!
		PFLEXFILEHEADER pHeader = (PFLEXFILEHEADER)m_pPaletteFlexFile;
		PFLEXFILEENTRY pEntry = (PFLEXFILEENTRY)(pHeader+1);
		UINT uiBytes = 0;
		for ( long e = 0; e < pHeader->count; e++ )
		{
			if ( (UINT)pEntry->offset >= uiFileLength || uiBytes >= uiFileLength )
				AfxThrowFileException(CFileException::genericException,101);

			uiBytes += pEntry->size;
			pEntry++;
		}

		if ( uiBytes + sizeof(FLEXFILEHEADER) + sizeof(FLEXFILEENTRY) * pHeader->count != uiFileLength )
			AfxThrowFileException(CFileException::genericException,102);

		// copy the first palette to the global one
		RGBQUAD* bmiColors = ((PBITMAPINFO)theApp.m_bitmapInfo)->bmiColors;
		pEntry = &((PFLEXFILEENTRY)(pHeader+1))[0];
		PCOLORENTRY pColors = (PCOLORENTRY)(m_pPaletteFlexFile + pEntry->offset);
		for ( int i = 0; i < 256; i++ )
		{
			bmiColors[i].rgbRed		= pColors[i].red   << 2;
			bmiColors[i].rgbGreen	= pColors[i].green << 2;
			bmiColors[i].rgbBlue	= pColors[i].blue  << 2;
		}
	}
}
#endif


// CPalDoc commands


BOOL CPalDoc::OnOpenDocument(LPCTSTR lpszPathName)
{
	if (!CDocument::OnOpenDocument(lpszPathName))
		return FALSE;

	// TODO:  Add your specialized creation code here

	return TRUE;
}


void CPalDoc::DeleteContents()
{
	// TODO: Add your specialized code here and/or call the base class
	if ( m_pPaletteFlexFile )
	{
		delete [] m_pPaletteFlexFile;
		m_pPaletteFlexFile = NULL;
	}

	CDocument::DeleteContents();
}
